const util = require('util');
const debug = util.debuglog('oil-game:exchangeEssence:action');
const {
  getUserExchangeData,    //查看内存中User的交易所表单信息
  initExchangeFrom,    //初始化交易所表单到缓存
  confirmExchange,    //确认交易
  cancelExchange,   //取消交易，更新石油数量
  getHistoryTax,    //获取近三日交易所信息
  getNowExchangeList,   //返回最新的N条交易完成数据
} = require('./cache');
const {
  userMoneyAndOil,    // 获取石油和金钱
  addMoney,   // 金钱增加
  addOil,    // 石油增加或减少
  getUserGrade,   //获取用户等级
  getUserGradeLimit,    // 获取用户等级限制
} = require('./api');
const {
  Msg,
  COUNT_DOWN_MAX,   //倒计时时长
  OIL_NUM_LIST,   //石油交易数量列表
  EXCHANGE_START_DATE,    //交易所开启时间
  EXCHANGE_END_DATE,    //交易所结束时间
} = require('./consts');
const {
	oilConfirmExchange,		//石油出售消息广播
} = require('./push');
const {
  dateIsBetween,    //计算当前时间是否处于一个时间段
  getFewDayAge,   //获取前几日的日期
} = require('./util');

//打开交易所
exports.openExchange = async function (session) {
  //获取用户等级，交易扣税，取消交易违约金，交易表单信息
  let {rank, tax, lateFee, exchangeFrom} = await getUserExchangeInfo.call(this, session);
  //获取前三日交易所的信息
  let history_tax = await getHistoryTax.call(this);
  let {tokyo, london, newYork} = history_tax;
  //rank 用户等级  tax 交易扣税  lateFee 取消交易违约金
  //exchangeFrom 交易表单信息{ id(表单ID), house(交易所), created_at(创建时间) }
  //tokyo 东京  london 伦敦  newYork 纽约
  let info = {rank, tax: `${tax}%`, lateFee: `${lateFee}%`, exchangeFrom, tokyo, london, newYork};
  return info;
}

//我要交易
exports.startExchange = async function (session) {
  let { uid } = session;
  debug(" uid = %s 我要交易", uid);
  //获取交易数量列表
  let oilNumList = OIL_NUM_LIST;

  //获取用户当前石油数量
  let moneyAndOil = await userMoneyAndOil.call(this, session);
  let oilNum = moneyAndOil ? moneyAndOil.essence_oil : 0;

  return {oilNumList, oilNum : oilNum ? oilNum : 0};
}

//立即交易
exports.initExchangeFrom = async function(session, oilNum, house){
  let { uid } = session;
  debug(" uid = %s oilNum = %s 初始化石油交易订单", uid, oilNum);
  //是否为营业时间
  if(!dateIsBetween(EXCHANGE_START_DATE, EXCHANGE_END_DATE)){
    throw new Error(Msg.NOT_BETWEEN_BUSINESS);
  }
  //查看交易数量是否大于拥有石油数量
  let moneyAndOil = await userMoneyAndOil.call(this, session);
  let oil = moneyAndOil ? moneyAndOil.essence_oil : 0;
  if(oil < oilNum) {
    debug(" uid = %s 初始化石油交易订单失败，石油数量不足", uid);
    throw new Error(Msg.OIL_NUM_ERROR);
  }
  //减少石油
  await addOil.call(this, session, -oilNum);
  //初始化交易所表单信息
  await initExchangeFrom.call(this, uid, oilNum, house);
}

//获取交易完成相关信息
exports.getFinishExchangeInfo = async function(session){
  let { uid } = session;
  debug(" uid = %s 获取交易完成相关信息", uid);
  let {created_at} = await getUserExchangeData.call(this, uid);
  //查看倒计时是否过期
  if(new Date(created_at).valueOf() >= new Date().valueOf() - COUNT_DOWN_MAX){
    debug(" uid = %s 获取交易完成相关信息失败，倒计时未结束", uid);
    throw new Error(Msg.COUNT_DOWN_NOT_END);
  }

  //获取内存中exchange信息
  let { oilNum, house } = await getUserExchangeData.call(this, uid);

  //获取昨日成交价
  let yesterdayPrice = await getYesterdayPrice.call(this, house);

  //获取扣税信息
  let {userFee} = await getUserGradeLimitInfo.call(this, session);
  //计算可得金额
  let money = await availableAmount.call(this, oilNum, house, userFee.trade_fee);

  return {
    oilNum,   //交易数量
    money,    //
    tax: `${userFee.trade_fee}%`,   //交易扣税
    lateFee: `${userFee.cancel_fee}%`,    //取消交易违约金
    yesterdayPrice
  };
}

//确认交易
exports.confirmExchange = async function(session){
  let { uid } = session;
  debug(" uid = %s 确认交易", uid);
  //获取交易所数据信息
  let exchange = await getUserExchangeData.call(this, uid);
  //判断订单状态
  if(exchange.type !== 0) {
    debug(" uid = %s 确认交易时订单异常", uid);
    throw new Error(Msg.FRON_STATUS_ERROR);
  }

  //获取扣税信息
  let {userFee} = await getUserGradeLimitInfo.call(this, session);
  //计算可得金额
  let money = await availableAmount.call(this, exchange.oilNum, exchange.house, userFee.trade_fee);

  //增加金钱
  await addMoney.call(this, session, money);

  //修改订单状态，更新可得金币
  await confirmExchange.call(this, uid, money);

	oilConfirmExchange.call(this, exchange.nickname, exchange.oilNum, money);
}

//取消交易
exports.cancelExchange = async function(session){
  let { uid } = session;
  debug("uid = %s 取消交易", uid);

  //获取交易所数据信息
  let { oilNum, type } = await getUserExchangeData.call(this, uid);
  //判断订单状态
  if(type !== 0){
    debug(" uid = %s 取消交易时订单异常", uid);
    throw new Error(Msg.FRON_STATUS_ERROR)
  }

  //获取扣税信息
  let {userFee} = await getUserGradeLimitInfo.call(this, session);
  //取消交易时扣除的手续费
  let cancelTax = parseInt(userFee.cancel_fee) / 100;   
  //减少石油数
  let subNum = parseInt(oilNum * cancelTax);    //减少的石油数 = 石油交易数量 * 违约金
  let cancelOilNum = oilNum - subNum;

  //取消交易后返还石油
  await addOil.call(this, session, cancelOilNum);
  
  //取消交易，更新订单状态
  await cancelExchange.call(this, uid);
}

//返回最新的N条交易完成数据
exports.getNowExchangeList = async function(num){
  return await getNowExchangeList.call(this, num);
}

//计算可得金额
async function availableAmount(oilNum, house, tax){
  //获取昨日成交价
  let yesterdayPrice = await getYesterdayPrice.call(this, house);
  //计算可得金额
  let money = Number(oilNum / 10 * yesterdayPrice * (1 - parseInt(tax) / 100)).toFixed(2);   //可得金额 = 石油数 / 10 * 昨日成交价 * 交易扣税
  return Number(money);
}

//获取当前用户等级和石油交易手续费，取消交易违约金
async function getUserGradeLimitInfo(session){
  //获取用户等级
  let rank = await getUserGrade.call(this, session);
  //获取用户扣税信息
  let userGradeLimit = await getUserGradeLimit.call(this, session);
  let userFee = null;
  for(let i = 0; i < userGradeLimit.length; i++){
    if(userGradeLimit[i].name == rank){
      userFee = userGradeLimit[i];
      break;
    }
  }
  return {rank, userFee};
}

exports.getUserFee = async function(session){
  let {rank, userFee} = await getUserGradeLimitInfo.call(this, session);
  return userFee.trade_fee;
}

//获取用户等级，交易扣税，取消交易违约金
async function getUserExchangeInfo(session) { 
  let { uid } = session;
  debug(" uid = %s 获取用户等级，交易扣税和取消交易违约金", uid);
  //获取用户等级和扣税信息
  let {rank, userFee} = await getUserGradeLimitInfo.call(this, session);
  //获取交易所数据信息
  let exchangeFrom  = await getUserExchangeData.call(this, uid);
  if(exchangeFrom){
    let {id, house, created_at} = exchangeFrom;
    //当前倒计时
    let countDownNum = parseInt((new Date(created_at).valueOf() + COUNT_DOWN_MAX - new Date().valueOf())/1000);
    exchangeFrom = {id, house, countDownNum};
  }
  //截取用户的exchange
  return { rank,   //用户等级
    tax: userFee.trade_fee,   //交易扣税
    lateFee: userFee.cancel_fee,    //取消交易违约金
    exchangeFrom,    //交易所信息
  };
}

//获取昨日成交价
async function getYesterdayPrice(house){
  //昨日成交价
  let history_tax = await getHistoryTax.call(this);
  let yesterday = getFewDayAge(-1);
  yesterday = yesterday.slice(yesterday.indexOf('-')+1).replace('-','/');
  let exchangeHouse = history_tax[house];
  let yesterdayPrice = 0;
  for(let i = 0; i < exchangeHouse.length; i++){
    if(exchangeHouse[i].date == yesterday){
      yesterdayPrice = Number(exchangeHouse[i].tax);
      break;
    }
  }
  if(yesterdayPrice == 0) throw new Error(Msg.NOT_YESTERDAT_PRICE);
  return yesterdayPrice;
}
